module ParseTest (spec) where

import Test.Hspec
import Hscm.Value
import Hscm.Parse (parse)


spec :: Spec
spec = do
    describe "read simple expr" $ do
        it "read string" $ do
            parse "\"this is a string\"" `shouldBe` Right (String "this is a string")

        it "read number" $ do
            parse "25" `shouldBe` Right (Integer 25)
            parse "-5" `shouldBe` Right (Integer $ -5)
            parse "-15" `shouldBe` Right (Integer $ -15)

        it "read double" $ do
            parse "25.1" `shouldBe` Right (Double $ 25.1)
            parse "-5.21" `shouldBe` Right (Double $ -5.21)
            parse "-0.0" `shouldBe` Right (Double $ -0.0)

        it "read symbol" $ do
            parse "symbol" `shouldBe` Right (Symbol "symbol")

        it "read symbol" $ do
            parse "symbol" `shouldBe` Right (Symbol "symbol")


    describe "read componet expr" $ do
        it "read symbol list" $ do
            parse "(a test)" `shouldBe` Right (List [Symbol "a", Symbol "test"])

        it "read symbol list list" $ do
            parse "(a (nested) test)" `shouldBe` Right (List [Symbol "a", List [Symbol "nested"], Symbol "test"])

        it "read symbol quote list" $ do
            parse "'(1 3 (\"this\" \"one\"))" `shouldBe` Right (List [Symbol "quote", List [Integer 1, Integer 3, List [String "this", String "one"]]])


    describe "read comment" $ do
        it "read begin comment" $ do
            parse "  ; A comment\n1" `shouldBe` Right (Integer 1)
            parse "; ???\n\"HHH\"" `shouldBe` Right (String "HHH")
            parse ";   \n (1 2 3)" `shouldBe` Right (List [Integer 1, Integer 2, Integer 3])

        it "read middle comment" $ do
            parse ";\n (1\n2\n3)" `shouldBe` Right (List [Integer 1, Integer 2, Integer 3])
            parse ";\n (1 ; first line\n2 ; 2 line\n3;12\n)" `shouldBe` Right (List [Integer 1, Integer 2, Integer 3])

        it "read end comment" $ do
            parse ";\n (1\n2\n3) ; hhh" `shouldBe` Right (List [Integer 1, Integer 2, Integer 3])
            parse ";\n (1 ; first line\n2 ; 2 line\n3;12\n)\n\n\n\n;last word!" `shouldBe` Right (List [Integer 1, Integer 2, Integer 3])